﻿using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.Extensions.DependencyInjection;
using PmSoft;

namespace Modules.Minio
{
    /// <summary>
    /// MinIo分布式对象存储服务
    /// </summary>
    [UseDI(ServiceLifetime.Scoped)]
    public class MinIoService
    {
        private readonly MinIoRepository repository;
        public MinIoService(MinIoRepository repository)
        {
            this.repository = repository;
        }

        /// <summary>通过Stream上传对象
        /// 通过Stream上传对象
        /// </summary>
        /// <param name="bucketName">存储桶名称</param>
        /// <param name="objectName">存储桶里的对象名称</param>
        /// <param name="data">要上传的Stream对象</param>
        /// <param name="size">流的大小</param>
        /// <param name="contentType">文件的Content type，默认是"application/octet-stream"</param>
        /// <param name="metaData">元数据头信息的Dictionary对象，默认是null</param>
        /// <returns></returns>
        public async Task PutObjectAsync(string bucketName, string objectName, byte[] data, long size, string contentType = "application/octet-stream", Dictionary<string, string>? metaData = null)
        {
            using MemoryStream stream = new MemoryStream(data);
            await repository.PutObjectAsync(bucketName, objectName, stream, size, contentType, metaData);
        }

        /// <summary>通过Stream上传对象
        /// 通过Stream上传对象
        /// </summary>
        /// <param name="bucketName">存储桶名称</param>
        /// <param name="objectName">存储桶里的对象名称</param>
        /// <param name="data">要上传的Stream对象</param>
        /// <param name="size">流的大小</param>
        /// <param name="contentType">文件的Content type，默认是"application/octet-stream"</param>
        /// <param name="metaData">元数据头信息的Dictionary对象，默认是null</param>
        /// <returns></returns>
        public async Task PutObjectAsync(string bucketName, string objectName, Stream data, long size, string contentType = "application/octet-stream", Dictionary<string, string>? metaData = null)
        {
            await repository.PutObjectAsync(bucketName, objectName, data, size, contentType, metaData);
        }


        /// <summary>下载对象指定区域的字节数组做为流。offset和length都必须传
        /// 下载对象指定区域的字节数组做为流。offset和length都必须传
        /// </summary>
        /// <param name="bucketName">存储桶名称</param>
        /// <param name="objectName">存储桶里的对象名称</param>
        /// <param name="offset">offset 是起始字节的位置</param>
        /// <param name="length">length是要读取的长度</param>
        /// <param name="callback">处理流的回调函数</param>
        /// <returns></returns>
        public async Task GetObjectAsync(string bucketName, string objectName, long offset, long length, Action<Stream> callback)
        {
            await repository.GetObjectAsync(bucketName, objectName, offset, length, callback);

        }

        /// <summary>生成一个给HTTP GET请求用的presigned URL。浏览器/移动端的客户端可以用这个URL进行下载，即使其所在的存储桶是私有的。这个presigned URL可以设置一个失效时间，默认值是7天。
        /// 生成一个给HTTP GET请求用的presigned URL。浏览器/移动端的客户端可以用这个URL进行下载，即使其所在的存储桶是私有的。这个presigned URL可以设置一个失效时间，默认值是7天。
        /// </summary>
        /// <param name="bucketName">存储桶名称</param>
        /// <param name="objectName">存储桶里的对象名称</param>
        /// <param name="expiresInt">失效时间（以秒为单位），默认是7天，不得大于七天</param>
        /// <param name="reqParams">额外的响应头信息，支持response-expires、response-content-type、response-cache-control、response-content-disposition</param>
        /// <returns></returns>
        public async Task<string> PresignedGetObject(string bucketName, string objectName, int expiresInt = 1000)
        {
            return await repository.PresignedGetObject(bucketName, objectName, expiresInt);
        }
    }
}
